
package analiseSintatica.Regras.Expressoes;

import java.util.LinkedList;

import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Contem as regras para Unario Posfixa
 * @author Nathalia
 */
public class RegraUnarioPosfixa extends Regra {

    protected static Regra instancia;
    protected static String estrutura = "<unario_posfixa> ::= <elemento> |  identificador <elementos_gerais>";

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraUnarioPosfixa() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraUnarioPosfixa getInstance() {
        if (instancia == null) {
            instancia = new RegraUnarioPosfixa();
        }
        return (RegraUnarioPosfixa) instancia;
    }

    /**
     * Realiza analise sintatica
     * @param listaTokens - Tokens do codigo
     * @return - Arvore sintatica
     * @throws Exception
     */	
	@Override
	public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException
       {
           ErroSintaticoException erros = new ErroSintaticoException();

           NoArvore naoterminalUnarioPosfixa = new NoArvore("<unarioposfixa>", false);
        try {
            NoArvore reconheceEl = reconhecerNaoTerminal(listaTokens, RegraElemento.getInstance());
            if(reconheceEl != null) naoterminalUnarioPosfixa.adicionaFilho(reconheceEl);
            else {
                naoterminalUnarioPosfixa.adicionaFilho(reconheceToken(listaTokens, "identificador",estrutura));
                try{
                reconheceEl = reconhecerNaoTerminal(listaTokens, RegraElementosGerais.getInstance());
                if(reconheceEl!=null)naoterminalUnarioPosfixa.adicionaFilho(reconheceEl);
                else{ }//ERRO
                }
                catch(ErroSintaticoException e){
                }
            }
        } catch (ErroSintaticoException e) {
            Logger.getLogger(RegraUnarioPosfixa.class.getName()).log(Level.SEVERE, null, e);
        }

        if (erros.size() != 0) {
            throw erros;
        }
           
        return naoterminalUnarioPosfixa;
	}
	

  
    @Override
    protected void setPrimeiro() {
        //P<unario_posfixa>  =  P<elemento> U identificador

      /* this.primeiro = RegraElemento.getInstance().getPrimeiro();
       this.primeiro.add("identificador");*/
        /* P<unario_posfixa>  =  P<elemento> U identificador
        -> P<unario_posfixa> = {identificador, "(", numeroInteiro , numeroFlutuante , charconst}*/
        this.primeiro.add("identificador");
        this.primeiro.add("(");
        this.primeiro.add("numeroInteiro");
        this.primeiro.add("numeroFlutuante");
        this.primeiro.add("charconst");
    }

    @Override
    protected void setSeguinte() {
       //S<unario_posfixa>   = S<unario_prefixa>
        //S(unario_prefixa) = S(cast)
        seguinte.add("(");
        seguinte.add("{");
        seguinte.add("identificador");
        seguinte.add("numeroInteiro");
        seguinte.add("numeroFlutuante");
        seguinte.add("charconst");
        seguinte.add("++");
        seguinte.add("--");
        seguinte.add("&");
        seguinte.add("*");
        seguinte.add("+");
        seguinte.add("-");
        seguinte.add("<");
        seguinte.add("<=");
        seguinte.add(">");
        seguinte.add(">=");
        seguinte.add("==");
        seguinte.add("!=");
        seguinte.add("&&");
        seguinte.add(";");
        seguinte.add(",");
        seguinte.add("}");
        seguinte.add(")");
    }

}
